<!--
 * @Description: 业务流程模型和标记法（Business Process Model and Notation）
 * @Version: 2.0
 * @Autor: wiz
 * @Date: 2024-07-09 13:42:36
 * @LastEditors: zss
 * @LastEditTime: 2024-12-04 13:28:11
-->

<template>
  <div class="init-container">
    <c-flowchart
      :compBoxInfo="GT_compBoxInfo"
      :config="conf"
      @compBoxInfo="cFlowchartMounted"
      @contextmenu-select="flowchartContextMenuSelected"
      @graphEditorState="graphEditorState"
    >
      <div slot="rightPanel" class="right-panel">
        <!-- <o-base-form
          :mode="1"
          @on-change="onRightFormAttrChange"
          @mounted="initRightForm"
        /> -->
      </div>
    </c-flowchart>
    <o-modal
      v-model="nodeDataModal"
      :title="$srv.getI18nByValue('节点自定义属性')"
      :size="[400, 300]"
      :mask="true"
      :tap-close="true"
      :keep-alive="true"
    >
      <div class="init-container" slot="content">
        <node-data-editor
          :compBoxInfo="GT_compBoxInfo"
          :selectCell="curModifyCell"
          :isShow="nodeDataModal"
        ></node-data-editor>
      </div>
    </o-modal>
  </div>
</template>

<script lang="ts">
import oModal from '@/components/base/modal/o-modal/index.vue';
import { GridLayout } from '@antv/layout';
import axios from 'axios';
import {
  getCf,
  I_cmd,
  ifs,
  N_cFlowchart,
  N_oContextMenu,
  cellContentMenuItem,
  nodeContentMenuItem,
  edgeContentMenuItem,
  graphToolbar,
  blankContentMenuItem,
  nodePorts,
  N_oSimpleToolbar,
  T_cmd,
  T_srv,
  Tsrv,
  vue
} from './config';
import nodeDataEditor from './nodeDataEditor.vue';

@T_srv.comp({
  components: {
    nodeDataEditor,
    oModal
  }
})
export default class girdFlowchart extends vue {
  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  @T_srv.prop({
    required: false,
    type: Array,
    default: null
  })
  localData: Array<any>;

  // 表格的config
  @T_srv.prop({
    type: Object,
    default: () => {}
  })
  tableCfg!: any;

  @T_srv.watch('localData', { deep: true })
  onLocalDataChange(localData: any) {
    this.transformGraphData(localData);
  }

  /* 组件名 */
  private name: string = 'girdFlowchart';

  private funName: string = '';

  private G_compName: string = this.name;

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  /* 指挥部 */
  private GT_command: I_cmd = new T_cmd();

  public conf: N_cFlowchart.I_conf = null;

  public cFlowchart: N_cFlowchart.cFlowchart = null;

  // 表格的实例
  public oBaseGrid: any = null;

  // 表格描述字段
  public tableDescField: string = '';

  public nodeDataModal: boolean = false;

  private curModifyCell: any = null;

  // 整理好的画布数据
  private graphData: any = null;

  public _localData: Array<any>;

  created() {
    // 如果父组件没有传参，那就产生一个
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.GT_command.init(this, this.GT_compBoxInfo);
    this.init();
  }

  mounted() {
    /* 向父组件发送实例 */
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    setTimeout(() => {
      this.handleBasicData();
      // 处理按钮权限
      // this.handleBtnPermission();
    }, 0);
  }

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }

  private init() {
    this.funName = this.name; // 当前配置中的功能名
    const cf = getCf();
    // this.handleBtnPermission(cf.toolbar.list);
    cf.regEvent = this.GT_command.regGraphEvents;
    cf.regToolbarEvent = this.GT_command.regToolbarEvents;
    cf.regShortcuts = this.GT_command.regShortcuts;
    this.conf = cf;
  }

  /* 组件挂载 */
  public cFlowchartMounted(compboxInfo: ifs.I_compBoxInfo) {
    this.cFlowchart = compboxInfo.TcompBox.getCompMergeName(
      compboxInfo.compID,
      'cFlowchart'
    );
  }

  /* 设置组件整体遮罩 */
  public setMask(p: boolean) {
    this.cFlowchart.isMask = p;
  }

  public getMask(p: boolean): boolean {
    return this.cFlowchart.isMask;
  }

  private handleBasicData() {
    this.oBaseGrid = this.GT_compBox.getCompMergeName(
      this.G_compID,
      'oBaseGrid'
    );
    const tableColumns = this.tableCfg.tableColumns;
    const decsField = tableColumns.find(itm => itm.isDes);
    if (Tsrv.noValue(decsField)) {
      this.tableDescField = 'id';
    } else {
      this.tableDescField = decsField.field;
    }
  }

  private handleBtnPermission(
    toolbar: N_oSimpleToolbar.I_Conf[] | (() => N_oSimpleToolbar.I_Conf[])
  ) {
    if (
      !Tsrv.noValue(toolbar) &&
      Array.isArray(toolbar) &&
      !Tsrv.noValue(this.tableCfg?.permission) &&
      !Tsrv.noValue(this.tableCfg?.toolbar)
    ) {
      const toolbarPermission = this.tableCfg.permission.find(
        itm => itm?.area === 'toolbar'
      );
      const editBtnPer = toolbarPermission.data['edit'];
      const editBtntoo = this.tableCfg?.toolbar['edit'];
      const graphEditBtn = toolbar.find(it => it.key === 'edit');
      graphEditBtn.disabled = true;
    }
  }

  public showNodeModal(cell: any) {
    this.curModifyCell = cell;
    this.nodeDataModal = true;
  }

  public nodeContentMenu(
    pos: N_oContextMenu.I_showPosition,
    e: N_cFlowchart.I_eventParams
  ) {
    const contentMenuItem = this.GT_command.handleMenuItems(e);
    if (this.cFlowchart.isDenyEdit()) {
      // 非编辑时不允许的右键菜单
      this.cFlowchart.displayContextMenu(
        pos,
        // contentMenuItem.filter(el => !/^add/.test(el.name)),
        [],
        e
      );
      return;
    }
    this.cFlowchart.displayContextMenu(pos, contentMenuItem, e);
  }

  public edgeContentMenu(
    pos: N_oContextMenu.I_showPosition,
    e: N_cFlowchart.I_eventParams
  ) {
    const contentMenuItem = this.GT_command.handleMenuItems(e);
    if (this.cFlowchart.isDenyEdit()) {
      // 非编辑时不允许的右键菜单
      this.cFlowchart.displayContextMenu(
        pos,
        // contentMenuItem.filter(el => !/^add/.test(el.name)),
        [],
        e
      );
      return;
    }
    this.cFlowchart.displayContextMenu(pos, contentMenuItem, e);
  }

  public blankContentMenu(
    pos: N_oContextMenu.I_showPosition,
    e: N_cFlowchart.I_eventParams
  ) {
    if (this.cFlowchart.isDenyEdit()) {
      // 非编辑时 选择过滤 右键菜单项
      this.cFlowchart.displayContextMenu(
        pos,
        blankContentMenuItem().filter(el => /blank:/.test(el.name)),
        e
      );
      return;
    }
    this.cFlowchart.displayContextMenu(pos, blankContentMenuItem(), e);
  }

  // 右键菜单选择
  public flowchartContextMenuSelected(
    key: string,
    cmd: N_cFlowchart.I_cFlowCmd
  ) {
    this.GT_command.flowchartContextMenuSelected(key, cmd);
  }

  public graphEditorState(v: N_cFlowchart.I_editorState) {
    this.GT_command.graphEditorState = v;
  }

  // 组装画布 节点/边 数据
  public transformGraphData(data: Array<any>) {
    const localData = Tsrv.utils.clone(data, true);
    this._localData = localData;
    const nodes: Array<any> = [];
    const edges: Array<any> = [];
    if (!Tsrv.noValue(localData)) {
      for (let i = 0; i < localData.length; i++) {
        const el = localData[i];
        // 描述字段的值
        let desc = Tsrv.utils.clone(this.tableDescField, true);
        Object.keys(el).forEach(k => {
          (k.indexOf(`m2o|${desc}`) > -1 || k.indexOf(`slc|${desc}`) > -1) &&
            (desc = k);
        });
        // 拼接节点
        const node = {
          id: el.id,
          size: {
            width: 80,
            height: 40
          },
          attrs: {
            body: {
              strokeWidth: 1,
              stroke: '#5F95FF',
              fill: '#EFF4FF',
              rx: 10,
              ry: 10
            },
            text: {
              fontSize: 12,
              fill: '#262626'
            },
            label: {
              text: Tsrv.getI18nBySrv(el[desc])
            }
          },
          data: {
            // row: el
            // pIDs: Tsrv.noValue(el?.p_id) ? [] : [el.p_id]
          },
          ports: { ...nodePorts }
        };
        nodes.push(node);
        // 拼接边
        if (el?.p_id) {
          const edge = {
            source: el.p_id,
            target: el.id,
            shape: 'grid-edge'
          };
          const isSame = edges.some(item => {
            return item.source === edge.source && item.target === edge.target;
          }); // 防止重复边
          !isSame && edges.push(edge);
        }
      }
    }
    //
    let graphData = null; // 布局
    const layoutObj = this.cFlowchart.getLayoutObj();
    if (!Tsrv.noValue(layoutObj)) {
      graphData = layoutObj.layout({ nodes, edges });
    }
    this.graphData = graphData;
    this.randerGraph();
  }

  // 写入画布 单元cell数据
  private randerGraph() {
    this.cFlowchart.reLoadDataFromJson(
      JSON.stringify(this.graphData) as string
    );
    // 编辑状态
    // this.cFlowchart.GT_cmd.graphEditorState = 'modify';
    this.cFlowchart.setShowMinimap(false);
    // 曲线修改···
    this.GT_command.handleBtnPermission(); // 按钮权限
    // setTimeout(() => {
    //   this.cFlowchart.graph.zoomToFit({
    //     padding: 20,
    //     preserveAspectRatio: true
    //   });
    // }, 100);
  }

  public getGraphData() {
    return this.graphData;
  }
}
</script>
<style lang="scss" scoped>
.right-panel {
  border: 1px solid #ccc;
  padding: 6px;
}
</style>
